package fr.labri.macchiato.ui;

import java.util.List;

import com.google.gwt.storage.client.Storage;
import com.smartgwt.client.types.Alignment;
import com.smartgwt.client.util.BooleanCallback;
import com.smartgwt.client.util.SC;
import com.smartgwt.client.widgets.Canvas;
import com.smartgwt.client.widgets.IconButton;
import com.smartgwt.client.widgets.events.ClickEvent;
import com.smartgwt.client.widgets.events.ClickHandler;
import com.smartgwt.client.widgets.form.fields.events.KeyPressEvent;
import com.smartgwt.client.widgets.form.fields.events.KeyPressHandler;
import com.smartgwt.client.widgets.layout.HLayout;
import com.smartgwt.client.widgets.layout.VLayout;
import com.smartgwt.client.widgets.menu.IconMenuButton;
import com.smartgwt.client.widgets.menu.Menu;
import com.smartgwt.client.widgets.menu.MenuItem;
import com.smartgwt.client.widgets.menu.MenuItemSeparator;
import com.smartgwt.client.widgets.menu.events.MenuItemClickEvent;
import com.smartgwt.client.widgets.toolbar.RibbonBar;
import com.smartgwt.client.widgets.toolbar.RibbonGroup;

import fr.labri.macchiato.core.model.Project;
import fr.labri.macchiato.core.service.Services;
import fr.labri.macchiato.core.technical.FrameworkException;
import fr.labri.macchiato.ui.preferences.AllPreferences;
import fr.labri.macchiato.ui.project.AddCartPrompt;
import fr.labri.macchiato.ui.project.NewProjectPrompt;
import fr.labri.macchiato.ui.project.ProjectLoader;
import fr.labri.macchiato.ui.project.ProjectWidget;


/**
 * The main panel of the application
 * 
 */
public class ApplicationPanel extends Canvas {
	private static final String DEFAULT_CART_NAME = "Ma liste de courses";
	private static final String DEFAULT_PROJECT_NAME = "Mes courses de la semaine";
	private static final double DEFAUT_PROJECT_BUDGET = 100;
	private static final double DEFAULT_CART_BUDGET = 10;
	private static final String PROJECT = "Projet";
	private static final String TOOLS = "Outils";
	private static final String CLEAN_CACHE = "Effacer les données enregistrées";
	private static final String SETTINGS = "Préférences";

	private VLayout mainLayout;
	private HLayout widgetLayout;

	private RibbonBar ribbonBar;

	private RibbonGroup projectGroup;
	private RibbonGroup toolsGroup;
	private String openedProject;
	private Menu loadMenu;
	private IconMenuButton loadProjectButton;

	/**
	 * Default Constructor.
	 */
	public ApplicationPanel() {
		setWidth100();
		setHeight100();
		mainLayout = new VLayout();
		mainLayout.setWidth100();
		mainLayout.setHeight100();
		addChild(mainLayout);

		ribbonBar = new RibbonBar();
		ribbonBar.setWidth("50%");
		ribbonBar.setHeight("15%");
		ribbonBar.setAlign(Alignment.CENTER);
		ribbonBar.setStyleName("ribbonBar");

		mainLayout.addMember(ribbonBar);

		widgetLayout = new HLayout();
		widgetLayout.setHeight("*");
		widgetLayout.setWidth("50%");
		mainLayout.addMember(widgetLayout);
		setAlign(Alignment.CENTER);
		setStyleName("applicationPanel");
		widgetLayout.setStyleName("widgetLayout");
		configureMenu();
		initialize(this);
	}

	/**
	 * Adds a widget to the application panel
	 * 
	 * @param child The widget to be added to the panel
	 */
	public void addWidget(Canvas child) {

		widgetLayout.addMember(child);

	}
	
	public static void initialize(ApplicationPanel main) {
		String projectName;

		Project newProject = null;

//		try {
//			newProject = ShareFunctionalities.getSharedProject();
//		} catch (FrameworkException e) {
//			SC.warn(e.getLocalizedMessage());
//		}

		if (newProject != null) {
			Services.getInstance().getProjectService().saveProject(newProject);
		} else {

			List<Project> projects = Services.getInstance().getProjectService().getAllProjects();

			if (projects == null || projects.size() == 0) {
				projectName = DEFAULT_PROJECT_NAME;
				newProject = Services.getInstance().getProjectService().newProject(projectName,
						DEFAUT_PROJECT_BUDGET);
				Services.getInstance().getProjectService().addCategory(projectName, DEFAULT_CART_NAME,
						DEFAULT_CART_BUDGET);
			} else {
				newProject = projects.get(0);
			}
		}
		main.setProjectWidget(new ProjectWidget(newProject.getName()));

		if (main.isDrawn())
			main.redraw();
		else
			main.draw();
	}

	private void configureMenu() {

		projectGroup = new RibbonGroup();
		projectGroup.setTitle(PROJECT);
		projectGroup.addControl(getNewProjectButton());
		projectGroup.addControl(getSaveProjectButton());
		projectGroup.addControl(getLoadProjectButton());

		toolsGroup = new RibbonGroup();
		toolsGroup.setTitle(TOOLS);
		toolsGroup.addControl(getSettingsButton());
		toolsGroup.addControl(getCleanCacheButton());

		ribbonBar.addMember(projectGroup);
		ribbonBar.addMember(toolsGroup);

	}

	private void projectCreationBehaviour(NewProjectPrompt prompt) {
		String projectName = prompt.getTextItem().getValueAsString();
		String budget = prompt.getBudgetItem().getValueAsString();
		Project project = null;
		try {
			project = Services.getInstance().getProjectService().newProject(projectName, Double.valueOf(budget));
			if (budget != null && !budget.trim().isEmpty()) {
				Services.getInstance().getProjectService().setBudget(projectName,Double.valueOf(budget));
			}
			final ProjectWidget projectWidget = new ProjectWidget(project.getName());
			setProjectWidget(projectWidget);
			prompt.destroy();
			SC.ask("Confirmation",
					"Le projet \""
							+ projectName
							+ "\" a bien été créé, voulez-vous lui ajouter un panier dès maintenant ?",
					new BooleanCallback() {

						public void execute(Boolean value) {
							if (value.equals(Boolean.TRUE)) {
								AddCartPrompt addCartPrompt = new AddCartPrompt();
								addCartPrompt.show();
								projectWidget.addPromptHandlers(addCartPrompt);
							}
						}
					});
		} catch (FrameworkException e) {
			SC.say(e.getLocalizedMessage());
			prompt.getValidateButton().setDisabled(false);
			prompt.getTextItem().focusInItem();
		}
	}

	private Canvas getNewProjectButton() {
		IconButton newProjectButton = new IconButton("Nouveau projet");
		newProjectButton.setOrientation("vertical");
		newProjectButton.setIcon("/icons/new.png");

		newProjectButton.addClickHandler(new ClickHandler() {

			public void onClick(ClickEvent event) {
				final NewProjectPrompt newProjectPrompt = new NewProjectPrompt();
				newProjectPrompt.show();
				newProjectPrompt.getValidateButton().addClickHandler(
						new ClickHandler() {

							public void onClick(ClickEvent event) {
								projectCreationBehaviour(newProjectPrompt);
							}
						});
				newProjectPrompt.getTextItem().addKeyPressHandler(
						new KeyPressHandler() {

							public void onKeyPress(KeyPressEvent event) {

								if (event.getKeyName().equals("Enter")) {
									projectCreationBehaviour(newProjectPrompt);
								}
							}
						});
			}
		});
		return newProjectButton;
	}

	private Canvas getSaveProjectButton() {
		IconButton saveProjectButton = new IconButton("Exporter le projet");
		saveProjectButton
				.setTooltip("Sauvegarde le projet en cours sur votre ordinateur");
		saveProjectButton.setOrientation("vertical");
		saveProjectButton.setIcon("/icons/save.png");

		saveProjectButton.addClickHandler(new ClickHandler() {

			public void onClick(ClickEvent event) {

//				Project project = Services.getInstance().getProjectService()
//						.loadProject(openedProject);
//				Encoder<Project> codec = Encoders.getInstance()
//						.getProjectEncoder();
//				String JSONProject = codec.encode(project);
//				FileSaver.saveFile(project.getName(), JSONProject);
			}
		});

		return saveProjectButton;
	}

	private Canvas getLoadProjectButton() {
		loadProjectButton = new IconMenuButton("Charger un projet");
		loadProjectButton.setOrientation("vertical");
		loadProjectButton.setLargeIcon("/icons/open.png");
		loadProjectButton.addClickHandler(new ClickHandler() {

			public void onClick(ClickEvent event) {
				loadProjectButton.showMenu();

			}
		});
		loadMenu = new Menu();
		updateLoadProjectMenu();

		return loadProjectButton;
	}

	private Canvas getCleanCacheButton() {
		IconButton cleanCacheButton = new IconButton(CLEAN_CACHE);
		cleanCacheButton.setOrientation("vertical");
		cleanCacheButton.setLargeIcon("/icons/sweep.png");

		cleanCacheButton.addClickHandler(new ClickHandler() {

			public void onClick(ClickEvent event) {
				Storage.getLocalStorageIfSupported().clear();
				Storage.getSessionStorageIfSupported().clear();
				ApplicationPanel.initialize(new ApplicationPanel());
			}
		});
    
		return cleanCacheButton;
	}

	private Canvas getSettingsButton() {

		IconButton settingsButton = new IconButton(SETTINGS);
		settingsButton.setOrientation("vertical");
		settingsButton.setLargeIcon("/icons/preferences.png");

		settingsButton.addClickHandler(new ClickHandler() {

			public void onClick(ClickEvent event) {
			//	new PreferencesWindow();
				new AllPreferences();
			}
		});

		return settingsButton;
	}

	/**
	 * Sets the widget to display
	 * 
	 * @param widget
	 */
	public void setProjectWidget(ProjectWidget widget) {
		int controlsLength = projectGroup.getControls().length;
		if (controlsLength == 4)
			projectGroup
					.removeControl(projectGroup.getControls()[controlsLength - 1]);
		projectGroup.addControl(widget.getAddCartButton());
		openedProject = widget.getProjectName();
		widgetLayout.removeMembers(widgetLayout.getMembers());
		widgetLayout.addMember(widget);
		updateLoadProjectMenu();
	}

	private void updateLoadProjectMenu() {
		loadMenu = new Menu();
		List<Project> projects = Services.getInstance().getProjectService()
				.getAllProjects();
		for (final Project project : projects) {
			MenuItem projectItem = new MenuItem(project.getName());
			projectItem
					.addClickHandler(new com.smartgwt.client.widgets.menu.events.ClickHandler() {

						public void onClick(MenuItemClickEvent event) {
							setProjectWidget(new ProjectWidget(project.getName()));

						}
					});
			loadMenu.addItem(projectItem);
			projectItem.setChecked(project.getName().equals(openedProject));
		}

		MenuItem loaderButton = new MenuItem("Depuis un fichier");
		loaderButton
				.addClickHandler(new com.smartgwt.client.widgets.menu.events.ClickHandler() {

					public void onClick(MenuItemClickEvent event) {
						new ProjectLoader(ApplicationPanel.this);

					}
				});
		loadMenu.addItem(new MenuItemSeparator());
		loadMenu.addItem(loaderButton);

		loadProjectButton.setMenu(loadMenu);

	}

}
